{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "zCBd-I8hCHvS"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "from tensorflow import keras\n",
        "from tensorflow.keras.datasets import mnist\n",
        "from tensorflow.keras.models import Model\n",
        "from tensorflow.keras.layers import Input, Dense, Lambda\n",
        "from tensorflow.keras import backend as K\n",
        "\n",
        "# Load MNIST dataset\n",
        "(x_train, _), (x_test, _) = mnist.load_data()\n"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Normalize and flatten images\n",
        "x_train = x_train.astype('float32') / 255.\n",
        "x_test = x_test.astype('float32') / 255.\n",
        "x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))\n",
        "x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))\n",
        "\n",
        "# Deterministic Autoencoder\n",
        "input_dim = x_train.shape[1]\n",
        "latent_dim = 2  # 2-dimensional latent space\n",
        "\n",
        "# Encoder\n",
        "input_img = Input(shape=(input_dim,))\n",
        "encoded = Dense(latent_dim, activation='relu')(input_img)\n",
        "\n",
        "# Decoder\n",
        "decoded = Dense(input_dim, activation='sigmoid')(encoded)\n",
        "\n",
        "# Define autoencoder model\n",
        "autoencoder = Model(input_img, decoded)\n",
        "\n",
        "# Compile and train the autoencoder\n",
        "autoencoder.compile(optimizer='adam', loss='binary_crossentropy')\n",
        "autoencoder.fit(x_train, x_train, epochs=10, batch_size=256, shuffle=True, validation_data=(x_test, x_test))\n",
        "\n",
        "# Extract the encoder model\n",
        "encoder = Model(input_img, encoded)\n",
        "\n",
        "# Generate latent space points using deterministic autoencoder\n",
        "latent_points_deterministic = encoder.predict(x_test)\n",
        "\n",
        "# Variational Autoencoder (VAE)\n",
        "# Reparameterization trick\n",
        "def sampling(args):\n",
        "z_mean, z_log_var = args\n",
        "    epsilon = K.random_normal(shape=(K.shape(z_mean)[0], latent_dim), mean=0., stddev=1.0)\n",
        "    return z_mean + K.exp(0.5 * z_log_var) * epsilon\n",
        "\n",
        "# Encoder\n",
        "input_img = Input(shape=(input_dim,))\n",
        "z_mean = Dense(latent_dim)(input_img)\n",
        "z_log_var = Dense(latent_dim)(input_img)\n",
        "z = Lambda(sampling)([z_mean, z_log_var])\n",
        "\n",
        "# Decoder\n",
        "decoded = Dense(input_dim, activation='sigmoid')(z)\n",
        "\n",
        "# Define VAE model\n",
        "vae = Model(input_img, decoded)\n",
        "\n",
        "# Compute VAE loss\n",
        "reconstruction_loss = keras.losses.binary_crossentropy(input_img, decoded)\n",
        "kl_loss = -0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)\n",
        "vae_loss = K.mean(reconstruction_loss + kl_loss)\n",
        "\n",
        "# Compile and train the VAE\n",
        "vae.add_loss(vae_loss)\n",
        "vae.compile(optimizer='adam')\n",
        "vae.fit(x_train, epochs=10, batch_size=256, shuffle=True, validation_data=(x_test, None))\n",
        "\n",
        "# Extract the encoder model\n",
        "encoder = Model(input_img, z_mean)\n",
        "\n",
        "# Generate latent space points using VAE\n",
        "latent_points_vae = encoder.predict(x_test)\n",
        "\n",
        "# Visualize the latent space\n",
        "plt.figure(figsize=(10, 5))\n",
        "plt.subplot(1, 2, 1)\n",
        "plt.scatter(latent_points_deterministic[:, 0], latent_points_deterministic[:, 1], c='b', cmap='rainbow')\n",
        "plt.title('Deterministic Autoencoder')\n",
        "\n",
        "plt.xlabel('Latent Dimension 1')\n",
        "plt.ylabel('Latent Dimension 2')\n",
        "plt.colorbar()\n"
      ],
      "metadata": {
        "id": "X5IWaFtoDgNU"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "plt.subplot(1, 2, 2)\n",
        "plt.scatter(latent_points_vae[:, 0], latent_points_vae[:, 1], c='b', cmap='rainbow')\n",
        "plt.title('Variational Autoencoder (VAE)')\n",
        "\n",
        "plt.xlabel('Latent Dimension 1')\n",
        "plt.ylabel('Latent Dimension 2')\n",
        "plt.colorbar()\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ],
      "metadata": {
        "id": "hgRH9xUsDofv"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}